package com.ophiux.micro.core.domain;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 实体生成SQL
 * @author chenh
 *
 */
public class EntitySqlBuilder {

	public final static String SQL_TYPE_INSERT = "insert";
	public final static String SQL_TYPE_UPDATE = "update";
	public final static String SQL_TYPE_DELETE = "delete";
	
	/**
	 * 实体生成sql
	 * @param sqlType	操作类型
	 * @param entity	实体
	 */
	public static <T> String build(String sqlType , Class<T> entity , String tableName) {
		
		String sql = "";
		
		T inst = null;
		
		try {
			inst = entity.newInstance();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} 
		
		//获取实体属性
		Field[] fields = null;//entity.getDeclaredFields();
		
		List<Field> fieldList = new ArrayList<Field>();
		Class<?> temp_clzz =  inst.getClass();
	 	while(temp_clzz != null && temp_clzz != Object.class){
//			fieldList.addAll(Arrays.asList(temp_clzz.getClass().getSuperclass().getDeclaredFields()));
			fieldList.addAll(Arrays.asList(temp_clzz.getDeclaredFields()));
			temp_clzz = temp_clzz.getSuperclass();
	 	}
	 	
	 	fields = new Field[fieldList.size()];
	 	int index = 0;
	 	for(Field f : fieldList) {
	 		fields[index] = f;
	 		index ++;
	 	}
	 	
		//获取实体类路径
		String clzPath = entity.getName();
		
		if(sqlType.equals(SQL_TYPE_INSERT)) {
			sql = buildInsertSQL(fields , tableName);
			sql = toIbatisXML("insert", "insert", clzPath, sql);
		}
		if(sqlType.equals(SQL_TYPE_UPDATE)) {
			sql = buildUpdateSQL(fields , tableName);
			sql = toIbatisXML("update", "update", clzPath, sql);
		}
		if(sqlType.equals(SQL_TYPE_DELETE)) {
			sql = buildDeleteSQL("ID" , tableName);
			sql = toIbatisXML("delete", "delete", "string", sql);
		}
		return sql;
	}
	
	private static String buildInsertSQL(Field[] fields , String tableName) {
		
		String sql = "insert into " + tableName;
		
		sql += " (" + "\n";
		
		String cloumn = "";
		
		String value = "";
		
		if(fields == null || fields.length == 0) return ""; 
		
		for(Field field : fields) {
			//获取属性名称
			String fieldName = field.getName();
			//组装列
			cloumn += " " + fieldName + "," + "\n";
			
			//组装值  先默认 VARCHAR
			value += "#{"+fieldName+" , jdbcType=VARCHAR}," + "\n";
		}
		
		//去除最后的","
		cloumn = cloumn.substring(0 , cloumn.length() - 2);
		value = value.substring(0 , value.length() - 2);
		
		//列完
		sql += cloumn + "\n )\n";
		sql += "values ( " + "\n";
		
		sql += value + "\n )";
		
		return sql;
	}
	
	private static String buildUpdateSQL(Field[] fields , String tableName) {
		
		String sql = "update " + tableName + "\n<trim prefix=\"set\" suffixOverrides=\",\">";
		//<if test="USER_NAME != '' and USER_NAME != null and USER_NAME != 'null'">USER_NAME = #{USER_NAME},</if>
		
		if(fields == null || fields.length == 0) return ""; 
		
		String items = "\n";
		int index = -1;
		for(Field field : fields) {
			//获取属性名称
			String fieldName = field.getName();
			index ++;
//			String dh = ",";
//			if(index == fields.length - 1) {
//				dh = "";
//			}
			
			//组装值  先默认 VARCHAR
			String item = "<if test=\""+ fieldName +" != \'\'" + 
			" and " + fieldName + " != null" +
		    " and " + fieldName + " != \'null\'\">" + 
			fieldName + " = #{" + fieldName + ", jdbcType=VARCHAR}" + "," + "</if>";
			
			items += item + "\n";
		}
		sql += items+"</trim>\n";
		//设置where条件，默认ID
		sql += " where ID = #{ID}";
		
		return sql;
	}
	
	/**
	 * 删除
	 * @param fields
	 * @param tableName
	 * @return
	 */
	private static String buildDeleteSQL(String ID , String tableName) {
		String sql = "delete " + tableName + " where " + ID +" = " + "#{" + ID +"}";
		return sql;
	}
	
	/**
	 * 生成ibatis xml
	 * @param elementName
	 * @param parameterType
	 * @return
	 */
	public static String toIbatisXML(String xmlID , String elementName , String parameterType , String content) {
		String xml = "<"+ elementName + 
				" id="+"\""+xmlID+"\"" +
				" parameterType="+"\""+parameterType+"\">";
		xml += "\n" + content + "\n";
		xml += "</"+elementName+">";
		return xml;
	}
	
	public static void main(String[] args) {
	//	String sql = EntitySqlBuilder.build(SQL_TYPE_INSERT, Customer.class , "t_customer_base");
//		String sql = EntitySqlBuilder.build(SQL_TYPE_UPDATE, Customer.class , "t_customer_base");
	//	String sql = EntitySqlBuilder.build(SQL_TYPE_DELETE, Customer.class , "t_customer_base");
	}
	
}
